/**
 * you can put a one sentence description of your library here.
 *
 * (c) 2010
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA  02111-1307  USA
 * 
 * @author		Leonardo Ariel Cortes Mendoza 
 * @modified	05/07/2010
 * @version		0.1.1
 */

package remixlab.malla;


import processing.core.*;

/**
 * This is a template class and can be used to start a new processing library or tool.
 * Make sure you rename this class as well as the name of the example package 'template' 
 * to your own library or tool naming convention.
 * 
 * @example Linea 
 * 
 * (the tag @example followed by the name of an example included in folder 'examples' will
 * automatically include the example in the javadoc.)
 *
 */

public class Malla {
	
	// myParent is a reference to the parent sketch
	PApplet myParent;

	int[][] mallaArray;
	int px0, px1, py0, py1;
	int mx0, mx1, my0, my1;
	float blockWidth, blockHeight;
	float x0, y0, x1, y1;
	int h,w, numOfColumn, cellSize, width, height;
	boolean middlePoint=false;
    int sw, sc, bg;
    int cellColor;
	
	public final static String VERSION = "0.1.1";
	

	/**
	 * a Constructor, usually called in the setup() method in your sketch to
	 * initialize and start the library.
	 * 
	 * @example Hello
	 * @param theParent
	 */
	public Malla(PApplet theParent){
	    myParent = theParent;
	    width = theParent.width;
	    height = theParent.height;
	    numOfColumn = 20;
            sw = 1;
            cellColor = 196;
            sc = 0;
            bg = 255;
	}
	
	/**
	 * This method initialize all the variables need by the mesh, must be called
	 * before to draw the mesh with drawMalla()
	 */
    public void initialize(){
        cellSize = width / numOfColumn;
	    mallaArray = new int[numOfColumn*4][numOfColumn*4];
    }
	
    /**
     * Draw the mesh on the screen of Processing
     */
	public void drawMalla() {
	    myParent.background(bg);
            myParent.strokeWeight(sw);
            myParent.stroke(sc);
	    h=0;
	    for(int j=0; j < height; j += cellSize/*blockWidth*/) {
	      w = 0;
	      for(int i=0; i < width; i += cellSize/*blockHeight*/ ) {
	        if(mallaArray[h][w] == 1) {
	          myParent.fill(cellColor);
	        } 
	        else {
	          myParent.noFill();
	        }
	        myParent.rect(i, j, cellSize-1, cellSize-1);
	        if(middlePoint){
	        	drawMidPoint(i+(cellSize/2), j);
		        drawMidPoint(i, j+(cellSize/2));
	        }
	        w++;
	      }
	      h++;
	    }
	    myParent.stroke(0);
	    myParent.line(x0, y0, x1, y1);
	}
	
	
	/**
	 * clean the mesh on the screen of Processing
	 */
	public void cleanMalla() {
	    h=0;
	    for(int j=0; j < height; j += cellSize) {
	      w = 0;
	      for(int i=0; i < width; i += cellSize) {
	        if(mallaArray[h][w] == 1) {
	        	mallaArray[h][w] = 0;
	        }
	        w++;
	      }
	      h++;
	    }
	}
	
	/**
	 * 
	 * @param x0
	 *          the x position of the mouse
	 * @return int
	 *          the x position on the mesh
	 */
	public int whereIsX(int x0) {
		h=0;
	    for(int j=0; j < height; j += cellSize) {
	      w = 0;
	      for(int i=0; i < width; i += cellSize ) {
	        if(x0 >= i && x0 <= i+cellSize-1){
	          return w;
	        }
	        w++;
	      }
	      h++;
	    }
	    return 0;
	}
	
	/**
	 * 
	 * @param y0
	 *          the y position of the mouse
	 * @return int
	 *          the y position on the mesh
	 */
	public int whereIsY(int y0) {
		h=0;
	    for(int j=0; j < height; j += cellSize) {
	      w = 0;
	      for(int i=0; i < width; i += cellSize ) {
	        if(y0 >= j && y0 <= j+cellSize-1){
	          return h;
	        }
	        w++;
	      }
	      h++;
	    }
	    return 0;
	}
	
        /**
	 * @param a
	 *         a String with some of this options "x0", "x1", "y0" or "y1"
	 * @return int
	 *         the position where is the point requested by the user
	 */
	public int getMallaPoints(String a) {
		if(a.equals("x0")) {
			return px0;
		}
		if(a.equals("x1")) {
			return px1;
		}
		if(a.equals("y0")) {
			return py0;
		}
		if(a.equals("y1")) {
			return py1;
		}
		return 0;
	}
	
        /**
	 * @param x 
	 *         the x position on the mesh
	 * @param y
	 *         the y position on the mesh
	 */
	public void drawPoint(int x, int y) {
		mallaArray[y][x] = 1;
	}
	
	/**
	 * @return int
	 * 			return the number of columns of the mesh
	 */
	public int getnumOfColumnn() {
		return numOfColumn;
	}
	
	/**
	 * @param numColumn
	 * 			set the number of columns of the mesh
	 */
	public void setNumOfColumn(int numColumn) {
		numOfColumn = numColumn;
	}
	
	/**
	 * draw a cross in the (x,y) position
	 * 
	 * @param x
     *          the x coordinate
     * @param y
     *          the y coordinate
	 */

	private void drawMidPoint(float x, float y) {
	    myParent.stroke(31,129,50, 96);
	    myParent.line(x+5, y, x-5, y);
	    myParent.line(x, y+5, x, y-5);
	    myParent.stroke(196);
	}
	
	/**
	 * draw middle points on the mesh
	 * 
	 * @param drawMidPoint
	 * 
	 */
	public void setMidPoints(boolean drawMidPoint) {
		middlePoint = drawMidPoint;
	}

	/**
	 * set the stroke weight of the mesh
	 * 
	 * @param sw
	 */
    public void setStrokeWeight(int sw){
        this.sw = sw;
    }
     
    /**
     * set the color of the cell in the mesh
     * 
     * @param c
     */
    public void setCellColor(int c) {
    	cellColor = c;
    }
    
    /**
     * set the stroke color of the lines in the mesh
     * 
     * @param sc
     */
    public void setStrokeColor(int sc) {
        this.sc = sc;
    }
    
    /**
     * set the background color of the mesh
     * 
     * @param bg
     */
    public void setBackgroundColor(int bg) {
        this.bg = bg;
    }

}